﻿using JinYuan.DAL.Models;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JinYuan.DAL
{
    public interface ISugarHepler : IDisposable
    {
        /// <summary>
        /// 初始化数据库连接
        /// </summary>
        /// <param name="connectionStr"></param>
        void SetConnectionStr(string connectionStr, SqlSugar.DbType dbType);

        #region 数据库管理
        /// <summary>
        /// 添加列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列信息</param>
        /// <returns></returns>
        bool AddColumn(string tableName, DbColumnInfo column);
        /// <summary>
        /// 添加主键
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <returns></returns>
        bool AddPrimaryKey(string tableName, string columnName);
        /// <summary>
        /// 备份数据库
        /// </summary>
        /// <param name="databaseName">数据库名</param>
        /// <param name="fullFileName">文件名</param>
        /// <returns></returns>
        bool BackupDataBase(string databaseName, string fullFileName);
        /// <summary>
        /// 备份表
        /// </summary>
        /// <param name="oldTableName">旧表名</param>
        /// <param name="newTableName">行表名</param>
        /// <param name="maxBackupDataRows">行数</param>
        /// <returns></returns>
        bool BackupTable(string oldTableName, string newTableName, int maxBackupDataRows = int.MaxValue);
        /// <summary>
        /// 创建表
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columns">列集合</param>
        /// <param name="isCreatePrimaryKey">是否创建主键</param>
        /// <returns></returns>
        bool CreateTable(string tableName, List<DbColumnInfo> columns, bool isCreatePrimaryKey = true);
        /// <summary>
        /// 删除列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <returns></returns>
        bool DropColumn(string tableName, string columnName);
        /// <summary>
        /// 删除约束
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="constraintName">约束名</param>
        /// <returns></returns>
        bool DropConstraint(string tableName, string constraintName);
        /// <summary>
        /// 删除表
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        bool DropTable(string tableName);
        /// <summary>
        /// 获取列信息
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="isCache">是否缓存</param>
        /// <returns></returns>
        List<DbColumnInfo> GetColumnInfosByTableName(string tableName, bool isCache = true);
        /// <summary>
        /// 获取自增列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        List<string> GetIsIdentities(string tableName);
        /// <summary>
        /// 获取主键
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        List<string> GetPrimaries(string tableName);
        /// <summary>
        /// 获取表集合
        /// </summary>
        /// <param name="isCache">是否缓存</param>
        /// <returns></returns>
        List<DbTableInfo> GetTableInfoList(bool isCache = true);
        /// <summary>
        /// 获取视图集合
        /// </summary>
        /// <param name="isCache">是否缓存</param>
        /// <returns></returns>
        List<DbTableInfo> GetViewInfoList(bool isCache = true);
        /// <summary>
        /// 检测列是否存在
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列名</param>
        /// <returns></returns>
        bool IsAnyColumn(string tableName, string column);
        /// <summary>
        /// 检测约束
        /// </summary>
        /// <param name="constraintName">约束名称</param>
        /// <returns></returns>
        bool IsAnyConstraint(string constraintName);
        /// <summary>
        /// 检测是否有任何系统表权限 
        /// </summary>
        /// <returns></returns>
        bool IsAnySystemTablePermissions();
        /// <summary>
        /// 检测表是否存在
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="isCache">是否缓存</param>
        /// <returns></returns>
        bool IsAnyTable(string tableName, bool isCache = true);
        /// <summary>
        /// 检测列是否自增列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列名</param>
        /// <returns></returns>
        bool IsIdentity(string tableName, string column);
        /// <summary>
        /// 检测列是否主键
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列名</param>
        /// <returns></returns>
        bool IsPrimaryKey(string tableName, string column);
        /// <summary>
        /// 重置列名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="oldColumnName">旧列名</param>
        /// <param name="newColumnName">新列名</param>
        /// <returns></returns>
        bool RenameColumn(string tableName, string oldColumnName, string newColumnName);
        /// <summary>
        /// 重置表数据
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        bool TruncateTable(string tableName);
        /// <summary>
        /// 修改列信息
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列信息</param>
        /// <returns></returns>
        bool UpdateColumn(string tableName, DbColumnInfo column);

        /// <summary>
        /// 获取数据库时间
        /// </summary>
        /// <returns>返回值</returns>
        DateTime GetDataBaseTime();
        #endregion

        #region  查询


        /// <summary>
        /// 查询所有
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        List<T> QueryAll<T>() where T : class, new();
        /// <summary>
        /// 查询-返回自定义数据
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="expression">返回值表达式</param> 
        /// <param name="whereLambda">查询表达式</param> 
        /// <returns>值</returns>
        TResult QuerySelect<T, TResult>(Expression<Func<T, TResult>> expression, Expression<Func<T, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 查询-返回自定义数据
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <typeparam name="TResult">返回值类型</typeparam>
        /// <param name="expression">返回值表达式</param> 
        /// <param name="whereLambda">查询表达式</param> 
        /// <returns>值</returns>
        List<TResult> QuerySelectList<T, TResult>(Expression<Func<T, TResult>> expression, Expression<Func<T, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 根据条件查询单条数据
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="whereLambda">查询表达式</param> 
        /// <returns></returns>
        T Query<T>(Expression<Func<T, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 根据条件异步查询单条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        Task<T> QueryAsync<T>(Expression<Func<T, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 根据条件查询排序数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        T Query<T>(Expression<Func<T, bool>> whereLambda = null, Expression<Func<T, object>> whereLambda2 = null, OrderByType byType = OrderByType.Desc) where T : class, new();



        /// <summary>
        /// 根据条件查询集合
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="whereLambda">过滤条件</param> 
        /// <returns>实体</returns>
        List<T> QueryWhereList<T>(Expression<Func<T, bool>> whereLambda = null) where T : class, new();
        /// <summary>
        /// 查询排序数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <returns></returns>
        List<T> QueryList<T>(QueryDescriptor query = null) where T : class, new();
        /// <summary>
        /// 查询前N条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sort">排序列名</param>
        /// <param name="Take">前N条数据</param>
        /// <param name="whereLambda">条件</param>
        /// <param name="byType">升序/降序</param>
        /// <returns></returns>
        List<T> QueryList<T>(string sort, int Take, Expression<Func<T, bool>> whereLambda = null, OrderByType byType = OrderByType.Desc) where T : class, new();
        /// <summary>
        /// 根据字段查询排列
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <param name="sort"></param>
        /// <param name="byType"></param>
        /// <returns></returns>
        List<T> QueryList<T>(string sort, Expression<Func<T, bool>> whereLambda = null, OrderByType byType = OrderByType.Asc) where T : class, new();
        /// <summary>
        /// 查询集合
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="sql">sql</param> 
        /// <returns>实体</returns>
        List<T> QuerySqlList<T>(string sql) where T : class, new();

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="query">过滤条件</param>
        /// <param name="totalCount">总行数</param>
        /// <returns>实体</returns>
        List<T> QueryPageList<T>(QueryDescriptor query, out int totalCount) where T : class, new();

        /// <summary>
        /// 通过多值查询数据集
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="inFieldName">字段名</param>
        /// <param name="inValues">数据集合</param>
        /// <returns></returns>
        List<T> In<T>(string inFieldName, List<dynamic> inValues) where T : class, new();

        /// <summary>
        /// 通过多值(主键)查询数据集
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="values">主键数据集合</param>
        /// <returns></returns>
        List<T> In<T>(List<dynamic> values) where T : class, new();

        /// <summary>
        /// 条件查询DataTable
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="whereLambda">查询表达式</param> 
        /// <returns>实体</returns>
        DataTable QueryDataTable<T>(Expression<Func<T, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 查询DataTable
        /// </summary> 
        /// <param name="sql">sql</param> 
        /// <returns>实体</returns>
        DataTable QueryDataTable(string sql);
        /// <summary>
        /// 查询单个值
        /// </summary> 
        /// <param name="sql">sql</param> 
        /// <returns>单个值</returns>
        object QuerySqlScalar(string sql);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="query">过滤条件</param>
        /// <param name="totalCount">总行数</param>
        /// <returns>DataTable</returns>
        DataTable QueryDataTablePageList<T>(QueryDescriptor query, out int totalCount) where T : class, new();

        #endregion

        #region 新增 
        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param>  
        /// <returns>操作影响的行数</returns>
        int Add<T>(T entity) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entitys">泛型集合</param>
        /// <returns>操作影响的行数</returns>
        int Add<T>(List<T> entitys) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="keyValues">字典集合（Key:列名 Value:值）</param> 
        /// <returns>操作影响的行数</returns>
        int Add<T>(Dictionary<string, object> keyValues) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param> 
        /// <returns>返回实体</returns>
        T AddReturnEntity<T>(T entity) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param> 
        /// <returns>返回自增列</returns>
        int AddReturnIdentity<T>(T entity) where T : class, new();
        /// <summary>
        /// 新增
        /// </summary> 
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param> 
        /// <returns>返回bool</returns>
        bool AddReturnBool<T>(T entity) where T : class, new();

        /// <summary>
        /// 新增
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entitys">泛型集合</param>
        /// <returns>返回bool</returns>
        bool AddReturnBool<T>(List<T> entitys) where T : class, new();
        #endregion

        #region 修改 
        /// <summary>
        /// 修改（主键是更新条件）
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象（必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件 </param> 
        /// <param name="lstIgnoreColumns">不更新的列</param>
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(T entity, List<string> lstIgnoreColumns = null, bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改（主键是更新条件）
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entitys"> 实体对象集合（必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件 </param> 
        /// <param name="lstIgnoreColumns">不更新的列</param>
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(List<T> entitys, List<string> lstIgnoreColumns = null, bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param> 
        /// <param name="where"> 条件 </param>  
        /// <param name="lstIgnoreColumns">不更新的列</param>
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(T entity, Expression<Func<T, bool>> where, List<string> lstIgnoreColumns = null,
            bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="update"> 实体对象 </param> 
        /// <param name="where"> 条件 </param>  
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(Expression<Func<T, object>> update, Expression<Func<T, bool>> where = null, bool isLock = true) where T : class, new();
        /// <summary>
        /// 修改+1
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="update"> 实体对象 </param> 
        /// <param name="where"> 条件 </param>  
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(Expression<Func<T, bool>> update, Expression<Func<T, bool>> where = null, bool isLock = true) where T : class, new();
        /// <summary>
        /// 修改单条数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <param name="isLock"></param>
        /// <returns></returns>
        int UpdateSingle<T>(T entity, Expression<Func<T, object>> where = null, Expression<Func<T, bool>> where2 = null, bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="keyValues">字典集合（Key:列名 Value:值）</param> 
        /// <param name="where"> 条件 </param>  
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Update<T>(Dictionary<string, T> keyValues, Expression<Func<T, bool>> where = null, bool isLock = true)
            where T : class, new();

        /// <summary>
        /// 批量修改需要更新的列
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entitys"> 实体对象（必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件 </param> 
        /// <param name="updateColumns">更新指定列</param>
        /// <param name="wherecolumns">条件(为空则以主键更新,反之需要把wherecolumns中的列加到UpdateColumns中)</param>
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int UpdateColumns<T>(List<T> entitys, Expression<Func<T, object>> updateColumns,
            Expression<Func<T, object>> wherecolumns = null, bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改 通过RowVer及主键Code 更新
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 </param> 
        /// <param name="lstIgnoreColumns">不更新的列</param>
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int UpdateRowVer<T>(T entity, List<string> lstIgnoreColumns = null, bool isLock = true) where T : class, new();

        /// <summary>
        /// 修改 通过RowVer及主键Code 更新
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="update"> 实体对象 </param>  
        /// <param name="where"> 更新条件 </param>  
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int UpdateRowVer<T>(Expression<Func<T, object>> update, Dictionary<string, object> where, bool isLock = true) where T : class, new();
        #endregion


        #region 删除

        /// <summary>
        /// 删除 通过主键数据
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="primaryKeyValues">主键值</param> 
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int DeleteByPrimary<T>(List<object> primaryKeyValues, bool isLock = true) where T : class, new();

        /// <summary>
        /// 根据实体类删除
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象（必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件 </param> 
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Delete<T>(T entity, bool isLock = true) where T : class, new();

        /// <summary>
        /// 初始化表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        void Delete<T>() where T : class, new();

        /// <summary>
        /// 根据实体类集合删除
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="entity"> 实体对象 （必须指定主键特性 [SugarColumn(IsPrimaryKey=true)]），如果是联合主键，请使用Where条件</param> 
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Delete<T>(List<T> entity, bool isLock = true) where T : class, new();

        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam>
        /// <param name="where"> 条件 </param> 
        /// <param name="isLock"> 是否加锁 </param> 
        /// <returns>操作影响的行数</returns>
        int Delete<T>(Expression<Func<T, bool>> where, bool isLock = true) where T : class, new();

        /// <summary>
        /// 通过多值(主键)删除数据集
        /// </summary>
        /// <typeparam name="T">泛型参数(集合成员的类型)</typeparam> 
        /// <param name="inValues">数据集合</param>
        /// <returns></returns>
        int DeleteIn<T>(List<dynamic> inValues) where T : class, new();

        #endregion
    }
}
